/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cloudbus.cloudsim.power.models.scheduling;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.cloudbus.cloudsim.*;
import org.cloudbus.cloudsim.core.CloudSimTags;
import org.cloudbus.cloudsim.core.SimEntity;
import org.cloudbus.cloudsim.core.SimEvent;

/**
 *
 * @author Márcio Costa Junior - University of São Paulo, Montana State University
 */
public class Client extends SimEntity{
    
    private int id;
    private double timeZone;
    private ArrayList<Vm> vmList;
    private ArrayList<Cloudlet> clList;
    private ArrayList<Middleware> midList;
    private int index;
    
    public Client(String name, int id, ArrayList<Middleware> midList, int index){
        super(name);
        
        this.id = id;
        this.vmList = new ArrayList<Vm>();
        this.clList = new ArrayList<Cloudlet>();
        this.midList = midList;
        this.index = index;
    }

    @Override
    public void startEntity() {
        Log.printLine("Client #" + id + " is starting...");
        //schedule(getId(), 0, CloudSimTags.CLIENT_SEND);
    }

    @Override
    public void processEvent(SimEvent ev) {
        switch (ev.getTag()){
			
                case CloudSimTags.CLIENT_SEND:
                        sendRequests();	
                break;
                default:
                       Log.printLine("Message not found");
		}
    }

    @Override
    public void shutdownEntity() {
        Log.printLine("Client #" + id + " is leaving simulation...");
    }
    
    protected void sendRequests(){
        try {
            midList.get(index).getClassList().get(0).getFrontEnd().createVmAndCloudlet(getVmList(), getClList());
        } catch (InterruptedException ex) {
            Log.printLine("It was not possible to send the requests");
        }
        
    }
    
    public void createVms(int brokerId, int start, int end, int mips[], int pesNumber, 
            int ram, long bw, long size, String vmm){

		// VM description
//		int[] mips = { 250, 500, 750, 1000 }; // MIPSRating
//		int pesNumber = 1; // number of cpus
//		int ram = 128; // vm memory (MB)
//		long bw = 2500; // bandwidth
//		long size = 2500; // image size (MB)
//		String vmm = "Xen"; // VMM name

		for (int i = start; i < end; i++) {
			getVmList().add(
				new Vm(i, brokerId, mips[i % mips.length], pesNumber, ram, bw, size, vmm, new CloudletSchedulerDynamicWorkload(mips[i % mips.length], pesNumber))
			);
		
                }
    }
    
    public void createCloulets(int brokerId, int start, int end, long length, int pesNumber, 
            long fileSize, long outputSize){

//		long length = 150000; // 10 min on 250 MIPS
//		int pesNumber = 1;
//		long fileSize = 300;
//		long outputSize = 300;

		for (int i = start; i < end; i++) {
			Cloudlet cloudlet = new Cloudlet(i, length, pesNumber, fileSize, outputSize, new UtilizationModelStochastic(), new UtilizationModelStochastic(), new UtilizationModelStochastic());
			cloudlet.setUserId(brokerId);
			cloudlet.setVmId(i);
			getClList().add(cloudlet);
		}
                
                

    }

    /**
     * @return the vmList
     */
    public ArrayList<Vm> getVmList() {
        return vmList;
    }

    /**
     * @return the clList
     */
    public ArrayList<Cloudlet> getClList() {
        return clList;
    }
}
